﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Net;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Animation;
using System.Windows.Shapes;
using FarseerGames.FarseerPhysics;
using FarseerGames.FarseerPhysics.Mathematics;
using FarseerGames.FarseerPhysics.Dynamics;

namespace Demo2
{
  public partial class Page : UserControl
  {
    private Storyboard gameLoop;
    private PhysicsSimulator physicsSimulator;
    private KeyHandler keyHandler;
    
    //The entity you can control via the keyboard
    private PhysicsBox playerBox;

    //Values used to move the playerBox around
    protected float forceAmount = 50000;
    protected float torqueAmount = 500000;

    //Todo: Instead of PhysicsBox, we need a "base" class. 
    //But this will work for this "Getting Started" purpose.
    //This list holds all the "elements" in the game, that should be updated at the gameloop tick.
    private List<PhysicsBox> entityList = new List<PhysicsBox>();

    public Page()
    {
      //Default Component Initializer created by VS2008, just leave it :)
      InitializeComponent();

      this.Loaded += new RoutedEventHandler(Page_Loaded);

      
    }

    protected void Page_Loaded(object sender, RoutedEventArgs e)
    {
      //Setup KeyHandler - This class is taken from the original 
      //Farseer Physics Engine release 1.0.0.5 (No reason to re-invent the wheel)
      keyHandler = new KeyHandler();
      keyHandler.Attach(this);

      //Setup GameLoop
      gameLoop = new Storyboard();
      gameLoop.Completed += new EventHandler(gameLoop_Completed);
      gameLoop.Duration = TimeSpan.FromMilliseconds(25); //The game will be updated every 25 millisecond
      this.Resources.Add("gameloop", gameLoop);

      //Setup PhysicsSimulator - No gravity applied this time
      physicsSimulator = new PhysicsSimulator(new Vector2(0, 0));

      //Add our PhysicsBox (PhysicsElement, Sprite, what ever you wanna call it)
      playerBox = new PhysicsBox(128, 128, 100);
      playerBox.Body.Position = new Vector2((float)this.Width / 2, (float)this.Height / 2);

      //Add the Body of our PhysicsBox to the physicsSimulator
      physicsSimulator.Add(playerBox.Body);
      //Add the actual PhysicsBox(UserControl) object to the list of UserControls to be updated in the gameloop event
      entityList.Add(playerBox);
      //Finally we add the PhysicsBox (UserControl) to the actual canvas where we want it to be rendered, so we can actually see it :)
      this.DrawingCanvas.Children.Add(playerBox);
      
      //This will start the actual gameloop - this is where your application actually starts (from the users point of view)
      gameLoop.Begin();
    }

    protected void gameLoop_Completed(object sender, EventArgs e)
    {

      //Update the entities from the inputs from the Keyboard
      HandleKeyboard();

      //Update the physics
      physicsSimulator.Update(.01f);

      //Update every entity in the game
      foreach (PhysicsBox box in entityList)
      {
        box.Update();
      }

      gameLoop.Begin();
    }

    private void HandleKeyboard()
    {
      Vector2 force = Vector2.Zero;
      force.Y = -force.Y;
      if (this.keyHandler.IsKeyPressed(Key.A)) { force += new Vector2(-forceAmount, 0); }
      if (this.keyHandler.IsKeyPressed(Key.S)) { force += new Vector2(0, forceAmount); }
      if (this.keyHandler.IsKeyPressed(Key.D)) { force += new Vector2(forceAmount, 0); }
      if (this.keyHandler.IsKeyPressed(Key.W)) { force += new Vector2(0, -forceAmount); }

      playerBox.Body.ApplyForce(force);

      float torque = 0;
      if (this.keyHandler.IsKeyPressed(Key.K)) { torque -= torqueAmount; }
      if (this.keyHandler.IsKeyPressed(Key.L)) { torque += torqueAmount; }
      playerBox.Body.ApplyTorque(torque);

    }
  }
}
